package com.example.tsbs.test;

import com.example.tsbs.config.Response;
import com.example.tsbs.util.MyLibrary;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.FloatByReference;
import com.sun.jna.ptr.PointerByReference;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;


/**
 * 一个java类
 * 运行环境是linux,需要打包生成jar文件放到linux环境运行
 */
@Slf4j
@Api(tags="test")
@RestController
@RequestMapping("/api")
public class HelloJNA {

    /**
     * 定义一个接口，默认的是继承Library ，如果动态链接库里的函数是以stdcall方式输出的，那么就继承StdCallLibrary
     * 这个接口对应一个动态链接(SO)文件
     */
    public interface LibraryAdd extends Library {
        LibraryAdd LIBRARY_ADD = Native.load("/root/danjidi/test/libTS_TARGET.so", LibraryAdd.class);
        LibraryAdd mLIBRARY_ADD = Native.load("/root/danjidi/test/libmid.so", LibraryAdd.class);
        LibraryAdd tLIBRARY_ADD = Native.load("/root/danjidi/test/libTS_TARGET_2.so", LibraryAdd.class);

        /**
         * 接口中只需要定义你要用到的函数或者公共变量，不需要的可以不定义
         * 映射so里面的函数，注意类型要匹配
         */
        int TS_target_free_frec(String TargetFileName, String[] BoundaryFileName,
                                Float SourceX0, Float SourceY0, Float SourceZ0,
                                Float SourceRX0, Float SourceRY0, Float SourceRZ0,
                                Float frec_low, Float frec_step, Float frec_high,
                                PointerByReference XData, PointerByReference YData, PointerByReference ZData);
        int TS_target_free_frec(String TargetFileName, String[] BoundaryFileName,
                                Float SourceX0, Float SourceY0, Float SourceZ0,
                                Float SourceRX0, Float SourceRY0, Float SourceRZ0,
                                Float frec_low, Float frec_step, Float frec_high,
                                FloatByReference XData, FloatByReference YData, FloatByReference ZData);

        int sayCplus(String ddTPath, String[] files, float SourceX0, float SourceY0, float SourceZ0,
                     float SourceRX0, float SourceRY0, float SourceRZ0, float frec_low, float frec_step, float frec_high,
                     com.example.tsbs.test.FloatByReference x,
                     com.example.tsbs.test.FloatByReference y,
                     com.example.tsbs.test.FloatByReference z);

    }

    @ApiOperation("TSTest")
    @PostMapping("/TSTest")
    public Response<?> TSTest() {
        String DDTPath = new String("/root/danjidi/ts/bechmark_double_all.DDT");
        String[] files = new String[]{"/root/danjidi/ts/water_steel(8mm)_water_V.dat",
                "/root/danjidi/ts/water_steel(4mm)_air_V.dat",
                "/root/danjidi/ts/water_steel(8mm)_water_T.dat",
                "/root/danjidi/ts/water_AL(10mm)_air_T.dat", null};
        float frec_high = 100.0f;
        float frec_low = 10.0f;
        float frec_step = 1000.0f;
        int data_len =(int)( (frec_high - frec_low) / frec_step )+ 1;
//        FloatByReference floatByReference1 = new FloatByReference();
//        Pointer pfloat1 = floatByReference1.getPointer();
//        FloatByReference floatByReference2 = new FloatByReference();
//        Pointer pfloat2 = floatByReference2.getPointer();
//        FloatByReference floatByReference3 = new FloatByReference();
//        Pointer pfloat3 = floatByReference3.getPointer();
//        PointerByReference XData = new PointerByReference(pfloat1);
//        PointerByReference YData = new PointerByReference(pfloat2);
//        PointerByReference ZData = new PointerByReference(pfloat3);

        // 通过PointerByReference创建一个空指针
        PointerByReference XData = new PointerByReference(Pointer.NULL);
        PointerByReference YData = new PointerByReference(Pointer.NULL);
        PointerByReference ZData = new PointerByReference(Pointer.NULL);


        System.out.println("kais");
        // 调用so映射的接口函数TS_target_free_frec(char *TargetFileName, char *BoundaryFileName[100],
        //float SourceX0, float SourceY0, float SourceZ0,float SourceRX0, float SourceRY0, float SourceRZ0,
        //float frec_low, float frec_step, float frec_high,float** XData, float** YData, float** ZData);
        int test = LibraryAdd.LIBRARY_ADD.TS_target_free_frec(DDTPath, files,
                0.0f, 0.0f, 5000.0f,
                0.0f, 0.0f, 5000.0f,
                frec_low, frec_step, frec_high, XData, YData, ZData);
//        int test = LibraryAdd.LIBRARY_ADD.TS_target_free_frec(ddt, dat, 0.0f, 0.0f, 5000.0f,
//                0.0f, 0.0f, 5000.0f, frec_low, frec_step, frec_high,
//                x, y, z);
        System.out.println("jies");

        // 获取分配的指针
        Pointer arrayPointer = XData.getValue();
        // 检查指针是否为NULL
        if (arrayPointer != Pointer.NULL) {
            // 获取float数组的第一个元素
            float firstElement = arrayPointer.getFloat(0);
            System.out.println("First element of the float array: " + firstElement);
            // 释放内存
            Native.free(Pointer.nativeValue(arrayPointer));
        } else {
            System.out.println("Failed to allocate float array.");
        }

        return Response.success("",test);
    }

    @ApiOperation("2mFloatByReference")
    @PostMapping("/2mFloatByReference")
    public Response<?> mid2() {
        String ddTPath = new String("/root/danjidi/ts/bechmark_double_all.DDT");
        String[] files = new String[]{"/root/danjidi/ts/water_steel(8mm)_water_V.dat",
                "/root/danjidi/ts/water_steel(4mm)_air_V.dat",
                "/root/danjidi/ts/water_steel(8mm)_water_T.dat",
                "/root/danjidi/ts/water_AL(10mm)_air_T.dat", null};
        float frec_low = 100f;
        float frec_step = 10f;
        float frec_high = 10000f;
        int data_len =(int)( (frec_high - frec_low) / frec_step )+ 1;
        com.example.tsbs.test.FloatByReference x = new com.example.tsbs.test.FloatByReference(10);
        com.example.tsbs.test.FloatByReference y = new com.example.tsbs.test.FloatByReference(1);
        com.example.tsbs.test.FloatByReference z = new com.example.tsbs.test.FloatByReference(1);

        // 调用so映射的接口函数
        System.out.println("开始调用so映射的接口函数");
        int test = LibraryAdd.mLIBRARY_ADD.sayCplus(ddTPath,files, 0f, 0f, 5000f,
                0f, 0f, 5000f, frec_low, frec_step, frec_high,x,y,z);
        System.out.println("开始函打印");
        float[] resx = x.getPointer().getFloatArray(0, 10);
        System.out.println("**"+ Arrays.toString(x.getPointer().getFloatArray(0, 10)));
        System.out.println("**"+ Arrays.toString(y.getPointer().getFloatArray(0, 1)));
        System.out.println("**"+ Arrays.toString(z.getPointer().getFloatArray(0, 1)));
        System.out.println("**test:"+test);
        return Response.success("");
    }


    @ApiOperation("test")
    @PostMapping("/test")
    public Response<?> t2Test() {
        String DDTPath = new String("/root/danjidi/ts/bechmark_double_all.DDT");
        String[] files = new String[]{"/root/danjidi/ts/water_steel(8mm)_water_V.dat",
                "/root/danjidi/ts/water_steel(8mm)_water_T.dat",
                "/root/danjidi/ts/water_steel(4mm)_air_V.dat",
                "/root/danjidi/ts/water_AL(10mm)_air_T.dat", null};
        float frec_high = 100.0f;
        float frec_low = 10.0f;
        float frec_step = 1000.0f;
        int data_len =(int)( (frec_high - frec_low) / frec_step )+ 1;

        com.example.tsbs.test.FloatByReference XData = new com.example.tsbs.test.FloatByReference(data_len*8);
        com.example.tsbs.test.FloatByReference YData = new com.example.tsbs.test.FloatByReference(data_len*8);
        com.example.tsbs.test.FloatByReference ZData = new com.example.tsbs.test.FloatByReference(data_len*8);

        System.out.println("kais");
        // 调用so映射的接口函数TS_target_free_frec
        int test = MyLibrary.INSTANTCE.TS_target_free_frec(DDTPath, files, 0.0f, 0.0f, 5000.0f,
                0.0f, 0.0f, 5000.0f, frec_low, frec_step, frec_high, XData, YData, ZData);
        System.out.println("jies");

        System.out.println("**"+ Arrays.toString(XData.getPointer().getFloatArray(0, data_len)));
        System.out.println("**"+ Arrays.toString(YData.getPointer().getFloatArray(0, data_len)));
        System.out.println("**"+ Arrays.toString(ZData.getPointer().getFloatArray(0, data_len)));

        return Response.success("",test);
    }



//        float[] XData = new float[data_len];
//        float[] YData = new float[data_len];
//        float[] ZData = new float[data_len];
//        FloatByReference XData = new FloatByReference();
//        FloatByReference YData = new FloatByReference();
//        FloatByReference ZData = new FloatByReference();
//        Pointer XData = new Memory(data_len * Native.getNativeSize(Float.TYPE));
//        Pointer YData = new Memory(data_len * Native.getNativeSize(Float.TYPE));
//        Pointer ZData = new Memory(data_len * Native.getNativeSize(Float.TYPE));
    // 分配内存以存放float数组
//        Pointer XData = Native.getDirectBufferPointer(FloatBuffer.allocate(data_len));
//        Pointer YData = Native.getDirectBufferPointer(FloatBuffer.allocate(data_len));
//        Pointer ZData = Native.getDirectBufferPointer(FloatBuffer.allocate(data_len));
//        FloatByReference[] XData = new FloatByReference[data_len];
//        FloatByReference[] YData = new FloatByReference[data_len];
//        FloatByReference[] ZData = new FloatByReference[data_len];
//        for(int i = 0; i < data_len; i++) {
//            XData[i] = new FloatByReference();
//            YData[i] = new FloatByReference();
//            ZData[i] = new FloatByReference();
//        }


//    @ApiOperation("1Pointer")
//    @PostMapping("/1Pointer")
//    public Response<?> mid() {
//        String DDTPath = new String("/root/danjidi/ts/bechmark_double_all.DDT");
//        String[] files = new String[]{"/root/danjidi/ts/water_steel(8mm)_water_V.dat",
//                "/root/danjidi/ts/water_steel(4mm)_air_V.dat",
//                "/root/danjidi/ts/water_steel(8mm)_water_T.dat",
//                "/root/danjidi/ts/water_AL(10mm)_air_T.dat", null};
//
//        int data_len = 4;
//        Pointer zData = new Memory(data_len * Native.getNativeSize(Float.TYPE));
//
//        System.out.println("kais");
//        int test = LibraryAdd.mLIBRARY_ADD.sayCplus(zData);
//        System.out.println("jies");
//
//        Native.free(Pointer.nativeValue(zData));
//        return Response.success("",zData.getFloat(0));
//    }
}

